import { getSnowflakeId } from "@/util/tools";
import { Prisma } from "@prisma/client";
import { UserInputError } from "apollo-server-koa";
import { Controller } from "egg";
import _ from "lodash";
import moment from "moment";
const qrcode = require("qrcode-terminal");

export default class HomeController extends Controller {
  public async index() {
    const { ctx } = this;

    ctx.body = "SUCCESS LOGON";
  }

  public async login() {
    const { ctx } = this;

    try {
      // const res = await ctx.service.geweChat.login.getTokenId();
      const res = {
        data: "5fd562107ec149a9be71c3a164afb12a",
      };

      // 请求微信登陆二维码
      const {
        ret,
        data: { uuid, appId, qrData },
      } = await ctx.service.geweChat.login.getLoginQrCode(res.data, {
        appId: "wx_NIp8p2er6NoxM86JRqeAw",
      });

      if (ret !== 200) {
        throw new UserInputError("获取微信登陆二维码☹️");
      }

      qrcode.generate(qrData, { small: true }, (q) => {
        console.log(q);
      });

      const data: Prisma.AdminUncheckedCreateInput = {
        id: getSnowflakeId(),
        wxAppId: appId,
        wxUuid: uuid,
        wxGeweToken: res.data,
      };

      await ctx.db.admin.upsert({
        where: {
          wxGeweToken: res.data,
        },
        create: data,
        update: {
          wxAppId: appId,
          wxUuid: uuid,
        },
      });
    } catch (error) {
      console.log("777", error);
    }

    ctx.body = "SUCCESS";
  }

  public async checkLogin() {
    const { ctx } = this;
    const { db } = ctx;

    const { id } = ctx.request.query;

    const admin = await db.admin.findUnique({ where: { id } });

    if (!admin) {
      throw new UserInputError("不存在");
    }

    const { wxGeweToken } = admin;

    const { ret, data } = await ctx.service.geweChat.login.checkLogin(wxGeweToken, {
      appId: admin?.wxAppId!,
      uuid: admin?.wxUuid!,
      captchCode: admin?.wxGeweToken,
    });

    console.log(JSON.stringify(data, null, 2), "datadatadata", ret, "retretretretret");

    if (ret !== 200) {
      throw new UserInputError("登陆失败");
    }

    const { loginInfo, status } = data;

    if (status === 2) {
      await db.admin.update({
        where: {
          id,
        },
        data: {
          wxid: loginInfo?.wxid,
          name: loginInfo?.nickName,
          wxAlias: loginInfo?.alias,
          phone: loginInfo?.mobile,
          status,
        },
      });
    }

    // await ctx.service.redisHelper.serWith("userInFo", { uuid: data.uuid, appId, loginInfo: data.loginInfo });

    // const res = await ctx.service.geweChat.login.setCallback({
    //   callbackUrl: "http://192.168.0.125:7004/callback",
    // });

    // if (res?.ret !== 200) {
    //   console.log("回调地址配置错误", res.msg);
    // }

    ctx.body = "SUCCESS";
  }

  public async cs() {
    const { ctx } = this;
    const { db } = ctx;

    const res = await ctx.service.siliconflow.index.userInfo();

    // const res = await ctx.service.geweChat.login.setCallback("5fd562107ec149a9be71c3a164afb12a", {
    //   callbackUrl: "http://192.168.0.125:7003/callback",
    //   token: "5fd562107ec149a9be71c3a164afb12a",
    // });

    // console.log(JSON.stringify(res, null, 2), "resresresres");

    //const res = await ctx.service.siliconflow.index.completions({ content: "啥是node" });

    // const res = await ctx.service.geweChat.contactPerson.fetchContactsList({ appId });

    // const res = await ctx.service.geweChat.message.postText({
    //   appId,
    //   toWxid: "wxid_wll6gmnmvlu921",
    //   content:
    //     "当然可以！以下是一个实现数组从小到大排列的JavaScript方法：\n\n```javascript\nfunction sortArray(arr) {\n    return arr.slice().sort((a, b) => a - b);\n}\n```\n\n### 方法解析：\n1. **参数**：`arr` 是需要排序的数组。\n2. **返回值**：返回一个按升序排列的新数组（原始数组不变）。\n3. **实现原理**：\n   - 使用 `slice()` 方法创建原始数组的浅拷贝\n   - 使用 `sort()` 方法对新数组进行排序\n   - `sort()` 方法的比较函数为 `(a, b) => a - b` ，用于按数字顺序排列\n\n### 示例用法：\n```javascript\nconst numbers = [3, 1, 4, 1, 5, 9];\nconst sortedNumbers = sortArray(numbers); // [1, 1, 3, 4, 5, 9]\n```\n\n### 其他注意事项：\n- 如果你只需要对原数组进行原地排序（不影响原始数据），可以不使用 `slice()`：\n  \n  ```javascript",
    // });

    //const res = await ctx.service.geweChat.account.checkOnline("5fd562107ec149a9be71c3a164afb12a", { appId });

    // const res = await ctx.service.geweChat.account.reconnection("5fd562107ec149a9be71c3a164afb12a", {
    //   appId: "wx_NIp8p2er6NoxM86JRqeAw",
    // });

    // const res = await ctx.service.geweChat.login.setCallback({
    //   callbackUrl: "http://192.168.0.125:7004/callback",
    // });

    //const res = await ctx.service.geweChat.account.logout({ appId });

    // console.log(res, "resresresresres");

    console.log(JSON.stringify(res, null, 2), "resresresresres");

    ctx.body = "SUCCESS";
  }

  public async callback() {
    const { ctx } = this;
    const { db } = ctx;

    // 获取原始请求头

    const body = ctx.request.body;

    let chattererId;
    let fromWxId;
    let content;

    const { Appid, TypeName, Wxid, Data } = body;
    const { MsgType, FromUserName, ToUserName, Content, PushContent } = Data;

    fromWxId = FromUserName?.string;
    content = Content.string;

    const admin = await db.admin.findUnique({
      where: {
        wxAppId: Appid,
      },
      select: {
        id: true,
        wxGeweToken: true,
        wxAppId: true,
        wxid: true,
      },
    });

    if (!admin) {
      throw new UserInputError(`Appid 搜索不到用户信息 - ${Appid}`);
    }
    const { wxGeweToken, wxAppId, wxid, id: adminId } = admin;

    if (FromUserName.string !== wxid) {
      chattererId = FromUserName.string;
    } else {
      chattererId = ToUserName.string;
    }

    const blacklistList = ["wxid_k3vyr3xiu83512", "weixin"];

    if (_.includes(blacklistList, FromUserName?.string)) {
      ctx.body = {
        ret: 200,
        msg: "操作成功",
      };
      return;
    }

    const create: Prisma.WXChatUncheckedCreateInput = {
      adminId,
      wxAppId: wxid!,
      chattererId,
      pushContent: PushContent,
    };
    const update: Prisma.WXChatUncheckedUpdateInput = {
      pushContent: PushContent,
    };

    const createList: Prisma.WXChatListUncheckedCreateWithoutWxChatInput[] = [];

    createList.push({
      createdAt: moment().toDate(),
      fromWxId,
      msgType: MsgType,
      content,
      adminId,
    });

    const wXChat = await db.wXChat.findUnique({
      where: {
        wxAppId_chattererId: {
          wxAppId: wxid!,
          chattererId,
        },
      },
      select: {
        id: true,
        wxChatList: {
          where: {
            msgType: 1,
          },
          orderBy: {
            createdAt: "desc",
          },
          select: {
            fromWxId: true,
            content: true,
          },
          take: 1000,
        },
      },
    });

    switch (MsgType) {
      case 1: {
        const messagesList: { role: "system" | "user" | "assistant"; content: string }[] = [];
        wXChat?.wxChatList.forEach((i) => {
          messagesList.unshift({
            role: i.fromWxId != Wxid ? "user" : "assistant",
            content: i.content,
          });
        });

        messagesList.push({
          role: "user",
          content,
        });

        console.log(JSON.stringify(messagesList, null, 2), "messagesListmessagesList");

        const { choices } = await ctx.service.siliconflow.index.completions({ messages: messagesList });
        console.log("解析完成");
        const res = await ctx.service.geweChat.message.postText(wxGeweToken, {
          appId: wxAppId,
          toWxid: fromWxId,
          content: choices[0].message.content,
        });

        createList.push({
          createdAt: moment().toDate(),
          fromWxId: wxid!,
          msgType: 1,
          content: `${choices[0].message.content}`,
          adminId,
        });

        break;
      }
      default: {
        const res = await ctx.service.geweChat.message.postText(wxGeweToken, {
          appId: wxAppId,
          toWxid: fromWxId,
          content: "当前消息暂不支持",
        });
      }
    }

    create.wxChatList = {
      create: createList,
    };
    update.wxChatList = {
      create: createList,
    };

    if (!wXChat) {
      await db.wXChat.create({
        data: create,
      });
    } else {
      await db.wXChat.update({
        where: {
          wxAppId_chattererId: {
            wxAppId: wxid!,
            chattererId,
          },
        },
        data: update,
      });
    }

    ctx.body = {
      ret: 200,
      msg: "操作成功",
    };
  }
}
